package edu.ccut.saturn.component;

import java.util.List;

/**
 * 平台提供的对SaturnData类型或SaturnData类型的列表数据进行后台验证的默认实现类。
 * 通过这个类可以引用在数据组件中配置的验证信息，并进行验证操作。
 * 
 * @author 谷钰
 * @author 温建
 * 
 * @version 1.0 2008.9.04
 * 
 * @see DefaultSaturnValidate
 * 
 */
public class SaturnDataDefaultValidate extends DefaultSaturnValidate {

	/**
	 * 首先判断要验证的数据是list还是saturnData；对saturnData对象进行验证时首先要得到生成SaturnData对象的数据组件信息，
	 * 从数据组件信息中可以得到每个属性的验证信息，根据验证信息对每个属性进行验证即可。
	 */
	@SuppressWarnings("unchecked")
	public void validate(Object value, Object[] args, ValidateResult result) {

		if (value instanceof List) {
			List saturnDataList = (List) value;

			if (saturnDataList.size() > 0) {
				Object tempValue = saturnDataList.get(0);

				if (tempValue != null && tempValue instanceof SaturnData) {
					IDataInfo saturnDataInfo = ((SaturnData) saturnDataList.get(0))
							.getSaturnDataInfo();

					for (int i = 0; i < saturnDataList.size(); i++) {
						validateSaturnDataList(
								(SaturnData) (saturnDataList.get(i)), args,
								saturnDataInfo, result, i);
					}
				}
			}
		}

		if (value instanceof SaturnData) {
			IDataInfo saturnDataInfo = ((SaturnData) value).getSaturnDataInfo();
			validateSaturnData((SaturnData) value, args, saturnDataInfo, result);
		}
	}

	private void validateSaturnDataList(SaturnData value, Object[] args,
			IDataInfo saturnDataInfo, ValidateResult result, int i) {

		ILogicContext context = null;

		if (args != null && args.length >= 1) {

			if (args[0] != null && args[0] instanceof ILogicContext) {
				context = (ILogicContext) args[0];
			}
		}

		doValidate(saturnDataInfo, result, context, value, getValidateRule(args));
	}

	private ValidateRule getValidateRule(Object[] args) {
		if (args != null && args.length >= 4) {
			return new ValidateRule((String) args[2], (String) args[3]);
		}
		return new ValidateRule(null, null);
	}

	private void validateSaturnData(SaturnData value, Object[] args,
			IDataInfo saturnDataInfo, ValidateResult result) {

		ILogicContext context = null;

		if (args != null && args.length >= 1) {

			if (args[0] != null && args[0] instanceof ILogicContext) {
				context = (ILogicContext) args[0];
			}
		}

		doValidate(saturnDataInfo, result, context, value, getValidateRule(args));
	}

	private void doValidate(IDataInfo saturnDataInfo, ValidateResult result,
			ILogicContext context, SaturnData value, ValidateRule validateRule) {

		for (String dataItemKey : saturnDataInfo.keySet()) {

			if (!validateRule.checkKeyNeedValidate(dataItemKey)) {
				continue;
			}
			IDataItem dataItem = saturnDataInfo.getDataItem(dataItemKey);

			if (dataItem != null) {
				IValidateUseInfo dataItemValidateUse = dataItem
						.getValidateUseInfo();

				if (dataItemValidateUse != null
						&& dataItemValidateUse.isValidate()) {

					String dataItemValueKey = dataItemValidateUse.getValueKey();
					List<IValidateInfo> validateInfos = dataItemValidateUse
							.getValidateInfos();

					Object dataItemValue = value.get(dataItemValueKey);

					if (validateInfos != null) {

						for (IValidateInfo validateInfo : validateInfos) {

							if (IValidateInfo.VALIDATETYPE_ERROR
									.equals(validateInfo.getValidateType())) {

								String dataItemValidateKey = validateInfo
										.getKey();

								if (!validateRule.isValidate(dataItemKey,
										dataItemValidateKey)) {

									continue;
								}
								IValidate validate = null;

								try {
									validate = ValidateManager.getInstance()
											.getValidate(dataItemValidateKey);

									validate.setErrorInfos(validateInfo
											.getErrorInfos());

								} catch (SaturnComponentException e) {
									e.printStackTrace();
								}
								Object[] dataItemArgs = this.getArgs(
										validateInfo.getArgs(), context, value);

								if (validate != null) {
									validate.validate(dataItemValue,
											dataItemArgs, result);
								}
							}
						}
					}
				}
			}
		}
	}

	private Object[] getArgs(List<String> validateArgs, ILogicContext context,
			SaturnData saturnData) {

		if (validateArgs != null && !validateArgs.isEmpty()) {
			Object[] args = new Object[validateArgs.size()];
			int i = 0;

			for (String validateArg : validateArgs) {
				args[i++] = this.getValue(validateArg, context, saturnData);
			}
			return args;
		}
		return null;
	}

	private Object getValue(String validatedKey, ILogicContext context,
			SaturnData saturnData) {
		Object value = saturnData.get(validatedKey);
		// 如果想传入参数是saturnData的某个属性且恰好为空，怎么办
		if (value == null) {
			return context.getValue(validatedKey);
		}

		return value;
	}

	// private class ValdateRule {
	//
	// private String includeStr;
	//
	// private String excludeStr;
	//
	// private Map<String, String[]> include;
	//
	// private Map<String, String[]> exclude;
	//
	// public ValdateRule(String includeStr, String excludeStr) {
	// this.includeStr = includeStr;
	// this.excludeStr = excludeStr;
	// initIncludeMap();
	// initExcludeMap();
	// }
	//
	// private void initExcludeMap() {
	//
	// if (this.excludeStr != null && !"".equals(this.excludeStr)) {
	// String[] excludes = this.excludeStr.split(",");
	//
	// if (excludes != null && excludes.length > 0) {
	// this.exclude = new HashMap<String, String[]>();
	//
	// for (String excludeItem : excludes) {
	// int index = excludeItem.indexOf("[");
	//
	// if (index > 0 && excludeItem.endsWith("]")) {
	// String key = excludeItem.substring(0, index);
	// String validateKeys = excludeItem.substring(
	// index + 1, excludeItem.length() - 1);
	//
	// String[] value = null;
	//
	// if ("*".equals(validateKeys)) {
	// value = new String[] { "*" };
	//
	// } else {
	// value = validateKeys.split(",");
	// }
	// this.exclude.put(key, value);
	//
	// } else {
	// this.exclude.put(excludeItem, new String[] { "*" });
	// }
	// }
	// }
	// }
	// }
	//
	// private void initIncludeMap() {
	//
	// if (this.includeStr != null && !"".equals(this.includeStr)) {
	// String[] includes = this.includeStr.split(",");
	//
	// if (includes != null && includes.length > 0) {
	// this.include = new HashMap<String, String[]>();
	//
	// for (String includeItem : includes) {
	// int index = includeItem.indexOf("[");
	//
	// if (index > 0 && includeItem.endsWith("]")) {
	// String key = includeItem.substring(0, index);
	// String validateKeys = includeItem.substring(
	// index + 1, includeItem.length() - 1);
	//
	// String[] value = null;
	//
	// if ("*".equals(validateKeys)) {
	// value = new String[] { "*" };
	//
	// } else {
	// value = validateKeys.split(",");
	// }
	// this.include.put(key, value);
	//
	// } else {
	// this.include.put(includeItem, new String[] { "*" });
	// }
	// }
	// }
	// }
	// }
	//
	// /**
	// * 判断是否对某一属性使用某项验证规则进行验证。 只有当待验证的属性满足被包含并且没有排除的情况下才进行验证。排除的优先级高于包含。
	// *
	// * @param key
	// * @param validateKey
	// * @return
	// */
	// public boolean isValidate(String key, String validateKey) {
	//
	// if (checkInclude(key, validateKey)
	// && !checkExclude(key, validateKey)) {
	//
	// return true;
	// }
	// return false;
	// }
	//
	// private boolean checkInclude(String key, String validateKey) {
	//
	// if (key != null && !"".equals(key)) {
	//
	// if (this.include == null) {
	// return true;
	// }
	//
	// if (this.include.keySet().contains(key)) {
	//
	// if (validateKey != null && !"".equals(validateKey)) {
	// String[] validateKeys = this.include.get(key);
	// if (validateKeys[0] != "*") {
	// for (String item : validateKeys) {
	// if (item.equals(validateKey)) {
	// return true;
	// }
	// }
	// return false;
	// }
	// }
	// return true;
	// }
	// }
	// return false;
	// }
	//
	// private boolean checkExclude(String key, String validateKey) {
	//
	// if (key != null && !"".equals(key)) {
	//
	// if (this.exclude == null) {
	// return false;
	// }
	//
	// if (this.exclude.keySet().contains(key)) {
	// String[] validateKeys = this.exclude.get(key);
	//
	// if (validateKey == null) {
	//
	// if (validateKeys[0] == "*") {
	// return true;
	//						
	// } else
	// return false;
	// }
	//
	// if (validateKey != null && !"".equals(validateKey)) {
	//
	// if (validateKeys[0] != "*") {
	//
	// for (String item : validateKeys) {
	//
	// if (item.equals(validateKey)) {
	// return true;
	// }
	// }
	// return false;
	// }
	// }
	// return true;
	// }
	// }
	// return false;
	// }
	// }
}
